//
//  WYWNetworkRequest.m
//  15WClient
//
//  Created by JinYong on 16/4/22.
//  Copyright © 2016年 15w. All rights reserved.
//

#import "WYWNetworkRequest.h"
#import "WYWNetworkSerialization.h"
#import "WYWHTTPAESEncoding.h"
#import <CommonCrypto/CommonDigest.h>
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

static const NSTimeInterval kNetworkTimeout    = 30.f;

@interface WYWNetworkRequest ()
@property (nonatomic,strong) CTTelephonyNetworkInfo *networkInfo;
@end

@implementation WYWNetworkRequest

+ (instancetype)sharedInstance{
    static dispatch_once_t once;
    static id singleton;
    dispatch_once(&once, ^{
        singleton = [[self alloc] init];
    });
    return singleton;
}


- (CTTelephonyNetworkInfo *)networkInfo{
    if (_networkInfo == nil) {
        _networkInfo = [[CTTelephonyNetworkInfo alloc] init];
    }
    
    return _networkInfo;
}

/**
 *  GUID
 *
 *  @return GUID
 */
- (NSString *) randomId{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    NSString *guid = (__bridge NSString *)string;
    NSString *guidCopy = [guid copy];
    CFRelease(string);
    return guidCopy;
}

/**
 *  URL编码
 *
 *  @param url 原始URL
 *
 *  @return 编码后的URL
 */
- (NSString *) urlEncoding:(NSString *)url{
    
    return [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
}

/**
 *  AES加密
 *
 *  @param plainSourceStringToEncrypt 加密前数据
 *  @param customKey                  AES key
 *
 *  @return 加密后数据
 */
- (NSString *)encryptString:(NSString *)plainSourceStringToEncrypt byKey:(NSString *)customKey{
    WYWHTTPAESEncoding *aesEncoding = [[WYWHTTPAESEncoding alloc] init];
    return [aesEncoding encryptString:plainSourceStringToEncrypt byKey:customKey];
}


#pragma mark - Request
- (NSURLRequest *)javaRequest:(NSString *)target params:(NSDictionary *)params method:(WYWNetworkRequestMethod)method{
    return [self javaRequest:target params:params method:method encoding:WYWNetworkEncodingGNUZip];
}


- (NSURLRequest *)javaRequest:(NSString *)target params:(NSDictionary *)params method:(WYWNetworkRequestMethod)method encoding:(WYWNetworkContentEncoding)encoding{
    if (!self.server || !self.server.length) {
        return nil;
    }
    // request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    // target url
    NSMutableString *targetUrl = [[NSMutableString alloc] init];
    if ([[self.server substringFromIndex:self.server.length - 1] isEqualToString:@"/"]) {
        // 以"/"结尾
        [targetUrl appendFormat:@"%@%@",self.server,target];
    }else{
        [targetUrl appendFormat:@"%@/%@",self.server,target];
    }

    if (method == WYWNetworkRequestMethodPOST) {
        // post
        //[targetUrl appendFormat:@"?randomId=%@",[self randomId]];
        // post请求需要对参数也加密编码
        NSString *body = [self urlEncoding:[self encryptString:[WYWNetworkSerialization jsonStringWithObject:params] byKey:self.javaKey]];
        NSData *bodyData = [[NSString stringWithFormat:@"req=%@", body] dataUsingEncoding:NSUTF8StringEncoding];
        
        // 设置URL
        [request setURL:[NSURL URLWithString:targetUrl]];
        // 设置post body
        [request setHTTPBody:bodyData];
        // 设置请求方法为POST
        [request setHTTPMethod:@"POST"];
        
        NSString *msgLength = [NSString stringWithFormat:@"%lu", (unsigned long)[bodyData length]];
        [request setValue:msgLength forHTTPHeaderField:@"Content-Length"];
        
    }else{
        // get、put、delete等
        // json->encrypt->urlencoding
        NSString *body = [self urlEncoding:[self encryptString:[WYWNetworkSerialization jsonStringWithObject:params] byKey:self.javaKey]];
        [targetUrl appendFormat:@"?req=%@&randomId=%@",body,[self randomId]];
        // 设置URL
        [request setURL:[NSURL URLWithString:targetUrl]];
        // 设置请求方法
        if (method == WYWNetworkRequestMethodPUT) {
            [request setHTTPMethod:@"PUT"];
        }else if(method == WYWNetworkRequestMethodGET){
            [request setHTTPMethod:@"GET"];
        }else if(method == WYWNetworkRequestMethodDELETE){
            [request setHTTPMethod:@"DELETE"];
        }
    }
    // 设置压缩方式，告诉网络请求模块是否需要进行解压缩
    if (encoding == WYWNetworkEncodingGNUZip) {
        [request setValue:@"gzip" forHTTPHeaderField:@"compress"];
    }else if(encoding == WYWNetworkEncodingLZSS){
        [request setValue:@"lzss" forHTTPHeaderField:@"compress"];
    }else{
        [request setValue:@"none" forHTTPHeaderField:@"compress"];
    }
    // 设置缓存策略
    request.cachePolicy = NSURLRequestReloadIgnoringCacheData;
    // 设置超时时间
    request.timeoutInterval = kNetworkTimeout;
    
    // 设置header
    [request setValue:self.version forHTTPHeaderField:@"version"];
    [request setValue:self.deviceID forHTTPHeaderField:@"deviceid"];
    [request setValue:self.clientType forHTTPHeaderField:@"ClientType"];
    [request setValue:self.osVersion forHTTPHeaderField:@"OsVersion"];
    [request setValue: @"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:self.sessionToken forHTTPHeaderField:@"SessionToken"];
    [request setValue:[[NSBundle mainBundle] bundleIdentifier] forHTTPHeaderField:@"AppName"];
    
    return request;
}

// 暂时不用
- (NSString *)getNetWorkStates{
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *children = [[[app valueForKeyPath:@"statusBar"]valueForKeyPath:@"foregroundView"]subviews];
    NSString *state = [[NSString alloc]init];
    int netType = 0;
    //获取到网络返回码
    for (id child in children) {
        if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
            //获取到状态栏
            netType = [[child valueForKeyPath:@"dataNetworkType"]intValue];
            
            switch (netType) {
                case 0:
                    state = @"None";
                    //无网模式
                    break;
                case 1:
                    state = @"2G";
                    break;
                case 2:
                    state = @"3G";
                    break;
                case 3:
                    state = @"4G";
                    break;
                case 4:
                    state = @"5G";
                    break;
                case 5:
                {
                    state = @"Wifi";
                }
                    break;
                default:
                    break;
            }
        }
    }
    //根据状态选择
    return state;
}

@end
